package com.freely.web.action;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.ServletContext;

import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.freely.domain.Location;
import com.freely.domain.ResponseMessage;
import com.freely.domain.User;
import com.freely.domain.ValidatorUser;
import com.freely.service.UserService;
import com.freely.util.Base64Util;
import com.freely.util.CommonUtil;
import com.freely.util.HttpUtil;
import com.freely.util.JSONUtil;
import com.freely.util.ResponseMessageUtil;
import com.freely.util.ValidatorUtil;
import com.opensymphony.xwork2.ActionSupport;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UserAction extends ActionSupport {
	@Resource(name = "userService")
	private UserService userService;

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	
	@Test
	public void testUpdate() {
		User user = new User();
		user.setUser_password("123");
		user.setUser_account("123456");
		user.setUser_name("zhangsan");
		user.setUser_email("123@qq.com");
		String json = JSON.toJSONString(user);
		JSONObject modifyObj = JSONObject.parseObject(json);
		JSONObject conditionObj = new JSONObject();
		conditionObj.put("user_name", (String)modifyObj.remove("user_name"));
		conditionObj.put("user_email", (String)modifyObj.remove("user_email"));
		userService.update(modifyObj, conditionObj);
	}

	/**
	 * 用户注册
	 * 
	 * @throws IOException
	 */
	public void register() throws IOException {
		JSONObject object = HttpUtil.parseJSON(null);
		if (object == null) {
			return;
		}
		// 判断客户端是否已经是通过验证码方式进行注册
		ServletContext context = ServletActionContext.getServletContext();
		String device_code = (String) object.get("device_code");
		Object obj = context.getAttribute(device_code);
		if (obj == null || !(obj instanceof Boolean)) {
			ResponseMessageUtil.response(false, null);
			return;
		}
		context.removeAttribute(device_code);

		User user = JSONObject.parseObject(object.toJSONString(), User.class);
		// 判断接收的数据是否符合规定，如果不符合则将不符合的规定返回
		String check = ValidatorUtil.validate(user);
		if (check != null) {
			ResponseMessageUtil.response(false, check);
			return;
		}
		// 查询数据库是否已经存在该用户或是否邮箱已被注册，存在则返回已存在信息，否则添加到数据库
		DetachedCriteria criteria = DetachedCriteria.forClass(User.class);
		criteria.add(Restrictions.or(Restrictions.eq("user_account", user.getUser_account()),
				Restrictions.eq("user_email", user.getUser_email())));

		List<User> result = userService.findByCondition(criteria);
		if (result == null) {
			user.setUser_name("用户" + CommonUtil.randomNumber(7));
			user.setUser_last_update_time(new Date());
			user.setUser_forbidden(false);
			user.setUser_image(CommonUtil.userImageInitializationLocation);
			try {
				userService.addUser(user);
			} catch (Exception e) {
				ResponseMessageUtil.response(false, null);
				return;
			}
			ResponseMessageUtil.response(true, "注册成功");
		} else {
			ResponseMessage<User> resultMessage = new ResponseMessage<>();
			resultMessage.setResult(false);
			User temp = new User();
			if (temp.getUser_account() != null) {
				temp.setUser_account("用户已被注册");
			} else {
				temp.setUser_email("邮箱已被注册");
			}
			ResponseMessageUtil.response(true, JSON.toJSONString(temp));
		}
	}

	/**
	 * 用户登录
	 * 
	 * @throws IOException
	 */
	public void login() throws IOException {
		JSONObject object = HttpUtil.parseJSON("用户名或密码错误");
		if (object == null) {
			return;
		}
		// 判断客户端是否已经是通过验证码方式进行注册
		ServletContext context = ServletActionContext.getServletContext();
		String device_code = (String) object.get("device_code");
		Object obj = context.getAttribute(device_code);
		if (obj == null || !(obj instanceof Boolean)) {
			ResponseMessageUtil.response(false, "验证码错误");
			return;
		}
		context.removeAttribute(device_code);

		User user = JSONObject.parseObject(object.toJSONString(), User.class);
		// 判断接收的数据是否符合规定，如果不符合则将不符合的规定返回
		String check = ValidatorUtil.validate(user);
		if (check != null) {
			ResponseMessageUtil.response(false, check);
			return;
		}
		// 到数据库查询数据是否匹配
		DetachedCriteria criteria = DetachedCriteria.forClass(User.class);
		criteria.add(Restrictions.eq("user_account", user.getUser_account()));
		criteria.add(Restrictions.eq("user_password", user.getUser_password()));
		List<User> result = userService.findByCondition(criteria);
		// 判断用户是否存在与是否被禁用
		if (result == null) {
			ResponseMessageUtil.response(false, "用户或密码不存在");
			return;
		}
		// 检查用户是否禁用
		User resultUser = result.get(0);
		if (resultUser.getUser_forbidden()) {
			ResponseMessageUtil.response(false, "用户被禁用");
			return;
		}
		// 将用户状态更改为在线
		JSONObject modifyObj = new JSONObject();
		modifyObj.put("user_online", true);
		JSONObject conditionObj = new JSONObject();
		conditionObj.put("user_id", user.getUser_id());
		int num = userService.update(modifyObj, conditionObj);
		if (num <= 0) {
			ResponseMessageUtil.response(false, "用户或密码不存在");
			return;
		}
		resultUser.setUser_online(true);
		// 过滤掉不需要发送的字段
		String resultData = JSONObject.toJSONString(result, JSONUtil.jsonFilter("user_password"));
		ResponseMessageUtil.response(true, resultData);
	}

	/**
	 * 重置密码
	 * 
	 * @throws IOException
	 */
	public void getBackPassword() throws IOException {
		JSONObject object = HttpUtil.parseJSON("无效的数据，请重新输入");
		if (object == null) {
			return;
		}
		// 验证验证码
		String user_email = object.getString("user_email");
		String user_password = object.getString("user_password");
		if (user_email == null || user_email.trim().length() == 0 || user_password == null
				|| user_password.trim().length() == 0) {
			ResponseMessageUtil.response(false, "无效的数据，请重新输入");
			return;
		}
		// 更新密码
		JSONObject modifyObj = new JSONObject();
		modifyObj.put("user_password", user_password);
		JSONObject conditionObj = new JSONObject();
		conditionObj.put("user_email", user_email);
		int num = userService.update(modifyObj, conditionObj);
		if (num <= 0) {
			ResponseMessageUtil.response(false, "无效的数据，请重新输入");
			return;
		}
		ResponseMessageUtil.response(true, "密码重置成功");
	}

	/**
	 * 退出登录
	 * 
	 * @throws IOException
	 */
	public void exit() throws IOException {
		JSONObject object = HttpUtil.parseJSON("无效的数据，退出失败");
		if (object == null) {
			return;
		}
		// 查询用户是否存在
		Long user_id = object.getLong("user_id");
		if (user_id == null) {
			ResponseMessageUtil.response(false, "无效的数据，退出失败");
			return;
		}
		DetachedCriteria criteria = DetachedCriteria.forClass(User.class);
		criteria.add(Restrictions.eq("user_id", user_id));
		List<User> result = userService.findByCondition(criteria);
		if (result == null) {
			ResponseMessageUtil.response(false, "无效的数据，退出失败");
			return;
		}
		// 将该用户的登录状态更新为离线
		User resultUser = result.get(0);
		JSONObject modifyObj = new JSONObject();
		modifyObj.put("user_online", false);
		modifyObj.put("user_last_login_time", new Date());
		JSONObject conditionObj = new JSONObject();
		conditionObj.put("user_id", resultUser.getUser_id());
		int num = userService.update(modifyObj, conditionObj);
		if (num <= 0) {
			ResponseMessageUtil.response(false, "无效的数据，退出失败");
			return;
		}
		ServletActionContext.getServletContext().removeAttribute(user_id.toString());
		ResponseMessageUtil.response(true, "退出成功");
	}

	/**
	 * 获取个人信息
	 * 
	 * @throws IOException
	 */
	public void getPersonInformation() throws IOException {
		JSONObject object = HttpUtil.parseJSON("获取个人信息失败");
		if (object == null) {
			return;
		}
		// 判断数据是否有效
		Long user_id = object.getLong("user_id");
		if (user_id == null) {
			ResponseMessageUtil.response(false, "获取个人信息失败");
			return;
		}
		DetachedCriteria criteria = DetachedCriteria.forClass(User.class);
		criteria.add(Restrictions.eq("user_id", user_id));
		List<User> result = userService.findByCondition(criteria);
		if (result == null) {
			ResponseMessageUtil.response(false, "获取个人信息失败");
			return;
		}
		User resultUser = result.get(0);
		// 判断用户是否被禁用
		if(resultUser.getUser_forbidden()) {
			ResponseMessageUtil.response(false, "该用户被禁用,获取失败");
			return;
		}
		// 将头像文件转换为base64编码字符串
		String imagePath = resultUser.getUser_image();
		File file = new File(imagePath);
		byte[] bufData = FileUtils.readFileToByteArray(file);
		String user_image = Base64Util.encode(bufData);
		resultUser.setUser_image(user_image);
		// 过滤掉不需要的字段
		String resultData = JSONObject.toJSONString(resultUser, JSONUtil.jsonFilter("user_id", "user_password",
				"user_last_login_time", "user_last_update_time", "user_online", "user_forbidden"));
		ResponseMessageUtil.response(true, resultData);
	}

	/**
	 * 更新个人信息
	 * 
	 * @throws IOException
	 */
	public void updatePersonInformation() throws IOException {
		JSONObject object = HttpUtil.parseJSON("无效的数据，更新失败");
		if (object == null) {
			return;
		}
		// 判断数据是否符合规则
		ValidatorUser validatorUser = object.toJavaObject(ValidatorUser.class);
		String validator = ValidatorUtil.validate(validatorUser);
		JSONObject validatorObj = new JSONObject();
		if(validator != null) {
			validatorObj = JSON.parseObject(validator);
		}
		String encodeImage = object.getString("user_image");
		byte[] decodeImage = null;
		// 判断是否更新头像并且更新的头像是否符合规则,符合则存储新头像的路径
		if(encodeImage != null) {
			decodeImage = Base64Util.decode(encodeImage);
			if((decodeImage[0] != -1 && decodeImage[1] != -40) || 
					(decodeImage.length > CommonUtil.imageMaxSize)) {
				validatorObj.put("user_image", "头像格式只支持jpg格式，并且大小不可超过100kb");
			}else {
				String fileName = CommonUtil.getUUID() + ".jpg";
				String hex = Integer.toHexString(fileName.hashCode());
				File parentFile = new File(CommonUtil.imagePath,hex.charAt(0) + File.separator + hex.charAt(1));
				if(!parentFile.exists()) {
					parentFile.mkdirs();
				}
				File image = new File(parentFile,fileName);
				object.put("user_image", image.getAbsolutePath());
			}
		}
		// 如果格式错误则更新失败
		if(validatorObj.size() > 0) {
			ResponseMessageUtil.response(false, JSON.toJSONString(validatorObj));
			return;
		}
		// 查询是否存在该用户
		DetachedCriteria criteria = DetachedCriteria.forClass(User.class);
		criteria.add(Restrictions.eq("user_id", object.getLong("user_id")));
		List<User> result = userService.findByCondition(criteria);
		if(result == null) {
			ResponseMessageUtil.response(false, "不存在该用户");
			return;
		}
		User user = result.get(0);
		// 配置更新语句
		JSONObject conditionObj = new JSONObject();
		conditionObj.put("user_id", Long.parseLong((String) object.remove("user_id")));
		int num = userService.update(object, conditionObj);
		if(num <= 0) {
			ResponseMessageUtil.response(false, "更新失败");
			return;
		}
		
		if(decodeImage != null) {
			// 删除旧头像
			File file = new File(user.getUser_image());
			if(file.exists()) {
				if(!file.getAbsolutePath().equals(CommonUtil.userImageInitializationLocation)) {
					file.delete();
				}
			}
			// 将新头像文件存储在硬盘
			FileUtils.writeByteArrayToFile(file, decodeImage);
		}
		ResponseMessageUtil.response(true, "更新成功");
	}
	/**
	 * 更新用户gps信息
	 * @throws IOException 
	 */
	public void updateLocation() throws IOException {
		JSONObject object = HttpUtil.parseJSON("无效的数据，更新失败");
		if (object == null) {
			return;
		}
		// 判断数据是否符合规则
		Location location = object.toJavaObject(Location.class);
		String validator = ValidatorUtil.validate(location);
		if(validator != null) {
			ResponseMessageUtil.response(false, validator);
			return;
		}
		// 将用户的经纬度信息存储在servletContext中
		ServletActionContext.getServletContext().setAttribute(Long.toString(location.getUser_id()), location);
		ResponseMessageUtil.response(true, "更新成功");
	}
	
}
